/**
 * 
 */
package com.xbang.core.dao.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.xbang.core.dao.annotation.Sentence;
import com.xbang.core.dao.support.GenericDaoSupport;


/**
 * @author dev.zhang
 *
 */
public class DynamicDaoInvocationHandler implements InvocationHandler {
    
    private GenericDaoSupport genericDaoSupport;
         
    /**
     * The constructor using GenericDaoSupport
     * 
     * @param genericDaoSupport
     */
    public DynamicDaoInvocationHandler(GenericDaoSupport genericDaoSupport) {
        this.genericDaoSupport = genericDaoSupport;
    }

    /* (non-Javadoc)
     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
     */
    @SuppressWarnings("unchecked")
	public Object invoke(Object proxy, Method method, Object[] parameters) throws Throwable {
        
        if(method.isAnnotationPresent(Sentence.class)) {
            Sentence sentence = method.getAnnotation(Sentence.class);
            boolean isSQL = sentence.sql();
            
            if(isSQL) {
                
                if(method.getReturnType() == int.class) {
                    
                    if(parameters == null || parameters.length == 0) {
                        return genericDaoSupport.queryForInt(sentence.value(), new HashMap());
                    }
                    
                    if(parameters.length == 1) {
                        if(parameters[0] instanceof Map)
                            return genericDaoSupport.queryForInt(sentence.value(), (Map)parameters[0]);
                        else
                            return genericDaoSupport.queryForInt(sentence.value(), parameters[0]);
                    } else {
                        throw new UnsupportedOperationException("SQL Query For Int result can only match one parameter.");
                    }
                    
                } else if(method.getReturnType() == List.class) {
                    
                    if(parameters == null || parameters.length == 0) {
                        return genericDaoSupport.queryForList(sentence.value(), new HashMap());
                    }
                    
                    if(parameters.length == 1) {
                        if(parameters[0] instanceof Map) {
                            return genericDaoSupport.queryForList(sentence.value(), (Map)parameters[0]);
                        } else {
                            return genericDaoSupport.queryForList(sentence.value(), parameters[0]);
                        }
                    } else {
                        throw new UnsupportedOperationException("SQL Query For List result can only match one parameter.");
                    }
                    
                } else {
                    throw new UnsupportedOperationException("Dao method can not be identified");
                }
                
            } else {
                
                if(method.getReturnType() == int.class) {
                    
                    if(parameters == null || parameters.length == 0) {
                        return genericDaoSupport.searchForInt(sentence.value(), new HashMap());
                    }
                    
                    if(parameters.length == 1) {
                        if(parameters[0] instanceof Map)
                            return genericDaoSupport.searchForInt(sentence.value(), (Map<String, Object>)parameters[0]);
                        else {
                            return genericDaoSupport.searchForInt(sentence.value(), parameters[0]);
                        }
                    } else {
                        throw new UnsupportedOperationException("HQL Query For Int result can only match one parameter.");
                    }
                    
                } else if(method.getReturnType() == List.class) {
                    
                    if(parameters == null || parameters.length == 0) {
                        return genericDaoSupport.searchForList(sentence.value(), new HashMap());
                    }
                    
                    if(parameters.length == 1) {
                        
                        if(parameters[0] instanceof Map)
                            return genericDaoSupport.searchForList(sentence.value(), (Map)parameters[0]);
                        else {
                            return genericDaoSupport.searchForList(sentence.value(), parameters[0]);
                        }
                    
                    } else {
                        return genericDaoSupport.searchForList(sentence.value(), parameters);
                    }
                    
                } else {
                    throw new UnsupportedOperationException("Dao method can not be identified");
                }
                
            }
            
        }
        
    	return null;
    }
    

}
